import { AbstractSeeder } from '../abstract';
import { Prisma, PrismaClient } from '../../../src/generated/prisma';
import { ROLE_DATA } from './role.data';

export default class RoleSeed extends AbstractSeeder {
  name = 'Role' as const;
  data = ROLE_DATA;

  async exec(tx: Prisma.TransactionClient): Promise<void> {
    const menus = await tx.menu.findMany({ select: { id: true, name: true } });
    const menuMap = new Map(menus.map(m => [m.name, m.id]));

    const roles = await Promise.all(
      this.data.map(r =>
        tx.role.upsert({
          where: { code: r.code },
          update: {},
          create: { name: r.name, code: r.code, remark: r.remark },
        }),
      ),
    );

    const roleMenuData: Prisma.RoleMenuCreateManyInput[] = [];
    roles.forEach(role => {
      const row = this.data.find(r => r.code === role.code)!;
      row.menuCodes.forEach(code => {
        const menuId = menuMap.get(code);
        if (menuId) roleMenuData.push({ roleId: role.id, menuId });
      });
    });
    if (roleMenuData.length) {
      await tx.roleMenu.createMany({ data: roleMenuData, skipDuplicates: true });
    }
  }
}

if (require.main === module) {
  const prisma = new PrismaClient();
  new RoleSeed()
    .run(prisma)
    .catch(e => {
      console.error(e)
      process.exit(1)
    })
    .finally(() => prisma.$disconnect());
}
